package ib080542d;
import java_cup.runtime.Symbol;

%%

%{	
	StringBuilder stringBuffer = new StringBuilder();
	String s;
	private Symbol newSymbol(int type) {
		return new Symbol(type, yyline + 1, yycolumn);
	}
	
	private Symbol newSymbol(int type, Object value) {
		return new Symbol(type, yyline + 1, yycolumn, value);
	}
%}

%cup
%class Lexer
%xstate COMMENT
%xstate STRING
%line
%char

%eofval{
	return newSymbol(Symbols.EOF);
%eofval}

%%

" "				{}
"\b"			{}
"\t"			{}
"\r\n"			{}
"\f"			{}
"program"		{ return newSymbol(Symbols.PROGRAM,		yytext()); }
"const"			{ return newSymbol(Symbols.CONST,		yytext()); }
"class"			{ return newSymbol(Symbols.CLASS,		yytext()); }
"extends"		{ return newSymbol(Symbols.EXTENDS,		yytext()); }
"void"			{ return newSymbol(Symbols.VOID,		yytext()); }
"if"			{ return newSymbol(Symbols.IF,			yytext()); }
"else"			{ return newSymbol(Symbols.ELSE,		yytext()); }
"while"			{ return newSymbol(Symbols.WHILE,		yytext()); }
"read"			{ return newSymbol(Symbols.READ,		yytext()); }
"print"			{ return newSymbol(Symbols.PRINT,		yytext()); }
"do"			{ return newSymbol(Symbols.DO,			yytext()); }
"new"			{ return newSymbol(Symbols.NEW,			yytext()); }
"return"		{ return newSymbol(Symbols.RETURN,		yytext()); }
"break"			{ return newSymbol(Symbols.BREAK,		yytext()); }
"="				{ return newSymbol(Symbols.EQ,			yytext()); }
"=="			{ return newSymbol(Symbols.EQEQ,		yytext()); }
"!="			{ return newSymbol(Symbols.NEQ,			yytext()); }
"+"				{ return newSymbol(Symbols.PLUS,		yytext()); }
"++"			{ return newSymbol(Symbols.PLUSPLUS,	yytext()); }
"-"				{ return newSymbol(Symbols.MINUS,		yytext()); }
"--"			{ return newSymbol(Symbols.MINUSMINUS,	yytext()); }
"*"				{ return newSymbol(Symbols.TIMES,		yytext()); }
"/"				{ return newSymbol(Symbols.DIV,			yytext()); }
"%"				{ return newSymbol(Symbols.PERCENT,		yytext()); }
">"				{ return newSymbol(Symbols.GT,			yytext()); }
">="			{ return newSymbol(Symbols.GTE,			yytext()); }
"<"				{ return newSymbol(Symbols.LT,			yytext()); }
"<="			{ return newSymbol(Symbols.LTE,			yytext()); }
","				{ return newSymbol(Symbols.COMMA,		yytext()); }
";"				{ return newSymbol(Symbols.SEMI,		yytext()); }
"||"			{ return newSymbol(Symbols.LOR,			yytext()); }
"&&"			{ return newSymbol(Symbols.LAND,		yytext()); }
"{"				{ return newSymbol(Symbols.OBRACE,		yytext()); }
"}"				{ return newSymbol(Symbols.CBRACE,		yytext()); }
"("				{ return newSymbol(Symbols.OPAREN,		yytext()); }
")"				{ return newSymbol(Symbols.CPAREN,		yytext()); }
"["				{ return newSymbol(Symbols.OSQUARE,		yytext()); }
"]"				{ return newSymbol(Symbols.CSQUARE,		yytext()); }
"."				{ return newSymbol(Symbols.DOT,			yytext()); }
"//"			{ yybegin(COMMENT); }
<COMMENT>.		{ yybegin(COMMENT); }
<COMMENT>"\r\n"	{ yybegin(YYINITIAL); }
[0-9]+			{ return newSymbol(Symbols.NUMBER, new Integer(yytext())); }
("true" | "false")				{ return newSymbol(Symbols.BOOLEAN, new Boolean(yytext())); }
([a-z]|[A-Z])[a-z|A-Z|0-9|_]*	{ return newSymbol(Symbols.IDENT, 	yytext()); }
"'"[\040-\176]"'"				{ return newSymbol(Symbols.CHARCONST, new Character(yytext().charAt(1))); }
"\""						{ yybegin(STRING); }
<STRING>\\t 				{ stringBuffer.append('\t'); yybegin(STRING); }
<STRING>\\n 				{ stringBuffer.append('\n'); yybegin(STRING); }
<STRING>\\r 				{ stringBuffer.append('\r'); yybegin(STRING); }
<STRING>[^\n\r\"\\]+ 		{ stringBuffer.append(yytext()); yybegin(STRING); }
<STRING>\\\" 				{ stringBuffer.append('\"'); yybegin(STRING); }
<STRING>\\					{ stringBuffer.append('\\'); yybegin(STRING); }
<STRING>\"					{
								yybegin(YYINITIAL);
						  		s = stringBuffer.toString();
						  		stringBuffer.setLength(0);
						  		return newSymbol(Symbols.STRING, s);
						  	}
.							{ return newSymbol(Symbols.INVALID, yytext()); }